#include <gtest/gtest.h>
#include <chrono>
#include <memory>
#include <vector>
#include "viml/garbage_collector.h"
#include "viml/object.h"
#include "viml/value.h"

using namespace viml;

// 模拟具体对象类，用于测试
class MockStringObject : public Object {
private:
    std::string data_;

public:
    explicit MockStringObject(const std::string& str)
        : Object(ObjectHeader::Type::STRING), data_(str) {}

    const std::string& data() const { return data_; }
    size_t size() const { return data_.length(); }

    void cleanup() override {
        do_cleanup();
    }

protected:
    void do_cleanup() override {
        // 清理资源
        data_.clear();
    }
};

/**
 * 简化的分代垃圾回收器测试类
 * 专注于测试已实现的基本功能
 */
class GenerationalGCSimpleTest : public ::testing::Test {
protected:
    void SetUp() override {
        gc_ = std::make_unique<GarbageCollector>();
        root_set_ = std::make_unique<GCRootSet>();
        gc_->set_root_set(root_set_.get());

        // 确保GC处于启用状态
        gc_->set_enabled(true);

        // 重置统计信息
        gc_->reset_stats();
        root_set_->reset_stats();
    }

    void TearDown() override {
        // 清理测试环境
        if (gc_) {
            gc_->reset_stats();
        }
        if (root_set_) {
            root_set_->clear_roots();
            root_set_->reset_stats();
        }
    }

    // 辅助方法：创建测试对象
    std::unique_ptr<MockStringObject> create_string(const std::string& str) {
        return std::make_unique<MockStringObject>(str);
    }

    // 辅助方法：测量执行时间
    template<typename Func>
    double measure_time(Func&& func) {
        auto start = std::chrono::high_resolution_clock::now();
        func();
        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        return duration.count() / 1000.0; // 转换为毫秒
    }

    std::unique_ptr<GarbageCollector> gc_;
    std::unique_ptr<GCRootSet> root_set_;
};

// ============================================================================
// 1. 基本GC功能测试
// ============================================================================

/**
 * 测试GC基本初始化和配置
 * 验证GC能够正确初始化并处于可用状态
 */
TEST_F(GenerationalGCSimpleTest, BasicInitialization) {
    EXPECT_NE(gc_, nullptr);
    EXPECT_NE(root_set_, nullptr);
    EXPECT_TRUE(gc_->is_enabled());

    // 验证初始统计信息
    auto stats = gc_->get_stats();
    EXPECT_EQ(stats.total_objects, 0);
    EXPECT_EQ(stats.total_collections, 0);

    // 验证根集初始状态
    auto root_stats = root_set_->get_stats();
    EXPECT_EQ(root_stats.total_roots, 0);
    EXPECT_EQ(root_stats.unique_objects, 0);
}

/**
 * 测试对象添加和基本管理功能
 * 验证对象能够正确添加到GC管理中
 */
TEST_F(GenerationalGCSimpleTest, BasicObjectManagement) {
    // 创建不同类型的对象
    auto str_obj = create_string("test_string");

    // 添加到GC管理
    gc_->add_object(str_obj.get());

    // 验证对象被正确添加
    auto stats = gc_->get_stats();
    EXPECT_EQ(stats.total_objects, 1);

    // 验证对象的代信息
    EXPECT_EQ(str_obj->get_generation(), 0); // 年轻代

    // 验证对象标记状态
    EXPECT_FALSE(str_obj->is_marked());
}

/**
 * 测试根集合的基本操作
 * 验证根对象能够正确添加、删除和查询
 */
TEST_F(GenerationalGCSimpleTest, BasicRootSetOperations) {
    auto root_obj = create_string("root_object");

    // 测试添加根对象
    root_set_->add_root(root_obj.get(), GCRootSet::RootType::GLOBAL);
    EXPECT_EQ(root_set_->size(), 1);
    EXPECT_EQ(root_set_->unique_size(), 1);
    EXPECT_TRUE(root_set_->contains(root_obj.get()));

    // 测试根对象类型
    EXPECT_EQ(root_set_->get_root_type(root_obj.get()), GCRootSet::RootType::GLOBAL);
    EXPECT_EQ(root_set_->count_type(GCRootSet::RootType::GLOBAL), 1);

    // 测试修改根对象类型
    root_set_->set_root_type(root_obj.get(), GCRootSet::RootType::STACK);
    EXPECT_EQ(root_set_->get_root_type(root_obj.get()), GCRootSet::RootType::STACK);
    EXPECT_EQ(root_set_->count_type(GCRootSet::RootType::STACK), 1);
    EXPECT_EQ(root_set_->count_type(GCRootSet::RootType::GLOBAL), 0);

    // 测试移除根对象
    EXPECT_TRUE(root_set_->remove_root(root_obj.get()));
    EXPECT_EQ(root_set_->size(), 0);
    EXPECT_FALSE(root_set_->contains(root_obj.get()));

    // 测试重复移除
    EXPECT_FALSE(root_set_->remove_root(root_obj.get()));
}

/**
 * 测试批量操作
 * 验证根集的批量添加和删除功能
 */
TEST_F(GenerationalGCSimpleTest, BatchRootSetOperations) {
    std::vector<Object*> objects;
    std::vector<std::unique_ptr<MockStringObject>> test_objects;

    // 创建多个对象
    for (int i = 0; i < 5; ++i) {
        auto obj = create_string("batch_object_" + std::to_string(i));
        objects.push_back(obj.get());
        test_objects.push_back(std::move(obj));
    }

    // 批量添加根对象
    root_set_->add_roots(objects, GCRootSet::RootType::USER);
    EXPECT_EQ(root_set_->size(), 5);
    EXPECT_EQ(root_set_->count_type(GCRootSet::RootType::USER), 5);

    // 测试获取特定类型的根对象
    auto user_roots = root_set_->get_roots(GCRootSet::RootType::USER);
    EXPECT_EQ(user_roots.size(), 5);

    // 清空特定类型的根对象
    root_set_->clear_roots(GCRootSet::RootType::USER);
    EXPECT_EQ(root_set_->size(), 0);
    EXPECT_EQ(root_set_->count_type(GCRootSet::RootType::USER), 0);
}

/**
 * 测试空对象的垃圾回收
 * 验证GC能够正确处理空集合的情况
 */
TEST_F(GenerationalGCSimpleTest, EmptyCollectionHandling) {
    // 在没有任何对象的情况下执行回收
    auto result = gc_->collect();

    // 验证回收过程正常完成
    EXPECT_EQ(result.objects_collected, 0);
    EXPECT_EQ(result.young_gen_collected, 0);
    EXPECT_GE(result.collection_time_ms, 0.0);

    auto stats = gc_->get_stats();
    EXPECT_EQ(stats.total_objects, 0);
    EXPECT_EQ(stats.total_collections, 1);
}

/**
 * 测试GC启用/禁用功能
 * 验证GC能够正确响应启用/禁用控制
 */
TEST_F(GenerationalGCSimpleTest, EnableDisableFunctionality) {
    // 创建一些对象
    std::vector<std::unique_ptr<MockStringObject>> test_objects;
    for (int i = 0; i < 5; ++i) {
        auto obj = create_string("test_object_" + std::to_string(i));
        gc_->add_object(obj.get());
        test_objects.push_back(std::move(obj));
    }

    // 禁用GC
    gc_->set_enabled(false);
    EXPECT_FALSE(gc_->is_enabled());

    // 执行回收（应该不执行任何操作）
    auto result_disabled = gc_->collect();
    EXPECT_EQ(result_disabled.objects_collected, 0);
    EXPECT_EQ(result_disabled.collection_time_ms, 0.0);

    auto stats_disabled = gc_->get_stats();
    EXPECT_EQ(stats_disabled.total_collections, 0); // 收集次数不应增加

    // 重新启用GC
    gc_->set_enabled(true);
    EXPECT_TRUE(gc_->is_enabled());

    // 执行回收（应该正常执行）
    auto result_enabled = gc_->collect();
    // 由于这些对象没有根引用，应该被回收
    EXPECT_GE(result_enabled.objects_collected, 0);
    EXPECT_GE(result_enabled.collection_time_ms, 0.0);

    auto stats_enabled = gc_->get_stats();
    EXPECT_EQ(stats_enabled.total_collections, 1); // 收集次数应该增加
}

/**
 * 测试统计信息的重置功能
 * 验证统计信息能够正确重置
 */
TEST_F(GenerationalGCSimpleTest, StatisticsReset) {
    // 创建对象并执行回收以产生统计数据
    std::vector<std::unique_ptr<MockStringObject>> test_objects;
    for (int i = 0; i < 5; ++i) {
        auto obj = create_string("test_object_" + std::to_string(i));
        gc_->add_object(obj.get());
        test_objects.push_back(std::move(obj));
    }

    gc_->collect();

    // 验证统计信息存在
    auto stats_before = gc_->get_stats();
    EXPECT_EQ(stats_before.total_collections, 1);

    // 重置统计信息
    gc_->reset_stats();

    // 验证统计信息被重置（只重置统计计数，对象计数保持不变）
    auto stats_after = gc_->get_stats();
    EXPECT_EQ(stats_after.total_collections, 0);
    EXPECT_EQ(stats_after.total_bytes_allocated, 0);
    EXPECT_EQ(stats_after.total_bytes_freed, 0);
    EXPECT_EQ(stats_after.average_collection_time_ms, 0.0);
    // total_objects 不重置为0，因为对象仍然在GC管理中
}

/**
 * 测试根集的完整性验证
 * 验证根集操作的正确性
 */
TEST_F(GenerationalGCSimpleTest, RootSetIntegrity) {
    std::vector<std::unique_ptr<MockStringObject>> test_objects;

    // 添加多个不同类型的根对象
    for (int i = 0; i < 3; ++i) {
        auto obj = create_string("root_object_" + std::to_string(i));
        root_set_->add_root(obj.get(),
            i == 0 ? GCRootSet::RootType::GLOBAL :
            i == 1 ? GCRootSet::RootType::STACK :
                     GCRootSet::RootType::REGISTER);
        test_objects.push_back(std::move(obj));
    }

    // 验证根集统计
    auto stats = root_set_->get_stats();
    EXPECT_EQ(stats.total_roots, 3);
    EXPECT_EQ(stats.unique_objects, 3);
    EXPECT_EQ(stats.global_roots, 1);
    EXPECT_EQ(stats.stack_roots, 1);
    EXPECT_EQ(stats.register_roots, 1);

    // 验证根集遍历
    auto all_roots = root_set_->get_roots();
    EXPECT_EQ(all_roots.size(), 3);

    // 验证根集完整性
    EXPECT_NO_THROW(root_set_->validate_integrity());

    // 测试锁定机制
    EXPECT_FALSE(root_set_->is_locked());
    root_set_->lock();
    EXPECT_TRUE(root_set_->is_locked());
    root_set_->unlock();
    EXPECT_FALSE(root_set_->is_locked());
}

/**
 * 测试带根对象的垃圾回收
 * 验证有根引用的对象不会被回收
 */
TEST_F(GenerationalGCSimpleTest, CollectionWithRoots) {
    std::vector<std::unique_ptr<MockStringObject>> test_objects;
    std::vector<Object*> root_objects;

    // 创建一些对象并添加到根集
    for (int i = 0; i < 3; ++i) {
        auto obj = create_string("persistent_object_" + std::to_string(i));
        root_objects.push_back(obj.get());
        gc_->add_object(obj.get());
        root_set_->add_root(obj.get());
        test_objects.push_back(std::move(obj));
    }

    // 创建一些临时对象（不添加到根集）
    std::vector<std::unique_ptr<MockStringObject>> temp_objects;
    for (int i = 0; i < 2; ++i) {
        auto obj = create_string("temp_object_" + std::to_string(i));
        gc_->add_object(obj.get());
        temp_objects.push_back(std::move(obj));
    }

    auto stats_before = gc_->get_stats();
    EXPECT_EQ(stats_before.total_objects, 5); // 3个持久 + 2个临时

    // 执行垃圾回收
    auto result = gc_->collect();

    // 验证临时对象被回收，持久对象存活
    EXPECT_EQ(result.objects_collected, 2); // 应该回收2个临时对象

    auto stats_after = gc_->get_stats();
    // 对象仍然在GC管理中，但临时对象应该被标记为不可达
    EXPECT_EQ(result.objects_collected, 2); // 确认回收了2个临时对象

    // 验证持久对象仍然有效
    for (auto* obj : root_objects) {
        EXPECT_TRUE(obj->is_valid_object());
        EXPECT_TRUE(root_set_->contains(obj));
    }
}

/**
 * 简单性能测试
 * 验证基本的性能特征
 */
TEST_F(GenerationalGCSimpleTest, BasicPerformanceTest) {
    const size_t PERFORMANCE_TEST_OBJECTS = 100;
    std::vector<std::unique_ptr<MockStringObject>> test_objects;

    // 性能测试：创建大量对象
    double creation_time = measure_time([&]() {
        for (size_t i = 0; i < PERFORMANCE_TEST_OBJECTS; ++i) {
            auto obj = create_string("perf_test_" + std::to_string(i));
            gc_->add_object(obj.get());
            test_objects.push_back(std::move(obj));
        }
    });

    auto stats_before = gc_->get_stats();
    EXPECT_EQ(stats_before.total_objects, PERFORMANCE_TEST_OBJECTS);

    // 性能测试：执行垃圾回收
    double collection_time = measure_time([&]() {
        auto result = gc_->collect();
        EXPECT_GT(result.objects_collected, 0);
    });

    // 性能验证（这些是基本要求，实际性能取决于实现）
    EXPECT_LT(creation_time, 1000.0);  // 创建时间应在1秒内
    EXPECT_LT(collection_time, 1000.0);  // 回收时间应在1秒内

    std::cout << "基本性能测试结果:" << std::endl;
    std::cout << "  创建对象数: " << PERFORMANCE_TEST_OBJECTS << std::endl;
    std::cout << "  创建时间: " << creation_time << "ms" << std::endl;
    std::cout << "  回收时间: " << collection_time << "ms" << std::endl;
}

/**
 * 测试GCManager的全局实例管理
 * 验证全局GC管理器的基本功能
 */
TEST_F(GenerationalGCSimpleTest, GCManagerBasicFunctionality) {
    // 设置全局根集
    GCManager::set_global_root_set(root_set_.get());

    // 获取多个实例引用
    auto& gc1 = GCManager::get_instance();
    auto& gc2 = GCManager::get_instance();

    // 验证是同一个实例
    EXPECT_EQ(&gc1, &gc2);

    // 测试全局操作
    GCManager::reset_global_stats();
    auto global_stats = GCManager::get_global_stats();
    EXPECT_EQ(global_stats.total_objects, 0);

    // 测试启用/禁用（使用GCManager的接口，而不是直接调用实例方法）
    GCManager::enable();
    EXPECT_TRUE(gc1.is_enabled());

    GCManager::disable();
    EXPECT_FALSE(gc1.is_enabled());

    GCManager::enable(); // 重新启用以便其他测试
}